package httpserver

import (
	"encoding/json"
	"errors"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/util/gconv"
	"os"
	"strconv"
	"time"
	"xr-game-server/core/cfg"
	"xr-game-server/core/constants/common"
	"xr-game-server/core/xrtoken"
	"xr-game-server/errercode"
)

// 接受请求
var canDo = true

func closeServer(sig os.Signal) {
	canDo = false
}

func MiddlewareAppAuth(r *ghttp.Request) {
	if cfg.GetServerCfg().DebugEnv {
		r.Middleware.Next()
		return
	}
	tokenStr := r.GetHeader(Token)
	userId := r.GetHeader(AuthId)
	if len(tokenStr) == common.Zero {
		r.Response.WriteJson(CreateFail(errercode.EmptyToken))
		return
	}
	if len(userId) == common.Zero {
		r.Response.WriteJson(CreateFail(errercode.EmptyUserId))
		return
	}
	if flag := xrtoken.HasAppToken(gconv.Uint64(userId)); !flag {
		r.Response.WriteJson(CreateFail(errercode.Token))
		return
	}
	r.Middleware.Next()
}

func MiddlewareCmsAuth(r *ghttp.Request) {
	if cfg.GetServerCfg().DebugEnv {
		r.Middleware.Next()
		return
	}
	tokenStr := r.GetHeader(Token)
	userId := r.GetHeader(AuthId)
	if len(tokenStr) == common.Zero {
		r.Response.WriteJson(CreateFail(errercode.EmptyToken))
		return
	}
	if len(userId) == common.Zero {
		r.Response.WriteJson(CreateFail(errercode.EmptyUserId))
		return
	}
	if flag := xrtoken.HasCmsToken(gconv.Uint64(userId)); !flag {
		r.Response.WriteJson(CreateFail(errercode.Token))
		return
	}
	r.Middleware.Next()
}

func middlewareCORS(r *ghttp.Request) {
	r.Response.CORSDefault()
	r.Middleware.Next()
}

// 记录前端请求日志
func middlewareLogReq(r *ghttp.Request) {
	//收到关机指令,服务器不再接受请求
	if !canDo {
		r.Response.WriteJson(CreateFail(int(errercode.ServerClose)))
		return
	}
	//设置请求时间
	r.Header.Set(DoTime, strconv.FormatInt(time.Now().UnixMilli(), 10))
	glog.Infof(gctx.New(), "收到前端请求,url=%v,ip=%v,authId=%v,请求数据=%v", r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), r.GetBodyString())
	r.Middleware.Next()
}

// cms应答结果
func customResponseMiddleware(r *ghttp.Request) {
	r.Middleware.Next()
	doTime := r.GetHeader(DoTime)
	if len(doTime) == common.Zero {
		doTime = strconv.FormatInt(time.Now().UnixMilli(), 10)
	}
	retTime := time.Now().UnixMilli() - gconv.Int64(doTime)
	var (
		res   = r.GetHandlerResponse()
		err   = r.GetError()
		ctx   = gctx.New()
		param any
	)
	code := errercode.Success
	if err != nil {
		var gErr *errercode.XError
		errors.As(err, &gErr)
		if gErr != nil {
			code = int(gErr.Code())
			param = gErr.Param
			glog.Infof(ctx, "错误码应答,处理时间=%vms,url=%v,ip=%v,authId=%v，响应错误码数据=%v", retTime, r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), code)
		} else {
			//清除系统自带的错误日志输出
			r.Response.ClearBuffer()
			code = errercode.SysError
			glog.Infof(ctx, "出现无法捕获的错误,处理时间=%vms,url=%v,ip=%v,authId=%v,请求数据=%s", retTime, r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), r.GetBodyString())
		}
	}
	r.Response.Header().Set("Content-Type", contentTypeJson)
	var respData any
	//发现有错误码
	if err != nil {
		respData = CreateFailAndParam(code, param)
	} else {
		respData = res
	}
	resp, _ := json.MarshalIndent(respData, "", " ")
	r.Response.Write(resp)
	if err == nil {
		if retTime >= LongDoTime {
			glog.Infof(ctx, "请求处理时间过长,处理时间=%vms,url=%v,ip=%v,authId=%v,响应数据=%s", retTime, r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), resp)
		} else {
			glog.Infof(ctx, "正常响应,处理时间=%vms,url=%v,ip=%v,authId=%v，响应数据=%s", retTime, r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), resp)
		}
	}
}

func apiResponseMiddleware(r *ghttp.Request) {
	r.Middleware.Next()
	doTime := r.GetHeader(DoTime)
	if len(doTime) == common.Zero {
		doTime = strconv.FormatInt(time.Now().UnixMilli(), 10)
	}
	retTime := time.Now().UnixMilli() - gconv.Int64(doTime)
	var (
		res   = r.GetHandlerResponse()
		err   = r.GetError()
		ctx   = gctx.New()
		param any
	)
	code := errercode.Success
	if err != nil {
		var gErr *errercode.XError
		errors.As(err, &gErr)
		if gErr != nil {
			code = int(gErr.Code())
			param = gErr.Param
			glog.Infof(ctx, "错误码应答,处理时间=%vms,url=%v,ip=%v,authId=%v，响应错误码数据=%v", retTime, r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), code)
		} else {
			//清除系统自带的错误日志输出
			r.Response.ClearBuffer()
			code = errercode.SysError
			glog.Infof(ctx, "出现无法捕获的错误,处理时间=%vms,url=%v,ip=%v,authId=%v,请求数据=%s", retTime, r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), r.GetBodyString())
		}
	}
	r.Response.Header().Set("Content-Type", contentTypeJson)
	var respData any
	//发现有错误码
	if err != nil {
		respData = CreateFailAndParam(code, param)
	} else {
		respData = CreateSuccess(res)
	}
	resp, _ := json.MarshalIndent(respData, "", " ")
	r.Response.Write(resp)
	if err == nil {
		if retTime >= LongDoTime {
			glog.Infof(ctx, "请求处理时间过长,处理时间=%vms,url=%v,ip=%v,authId=%v,响应数据=%s", retTime, r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), resp)
		} else {
			glog.Infof(ctx, "正常响应,处理时间=%vms,url=%v,ip=%v,authId=%v，响应数据=%s", retTime, r.URL.RequestURI(), r.Host, r.GetHeader(AuthId), resp)
		}
	}

}
